package com.duobaoyu.dby.supply.biz.strategy.message.order.confirm;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.duobaoyu.dby.channel.adapter.bean.message.order.LinkedMallConfirmOrderMessage;
import com.duobaoyu.dby.channel.adapter.enums.BizMessageTypeEnum;
import com.duobaoyu.dby.channel.adapter.enums.ChannelCodeEnum;
import com.duobaoyu.dby.common.mybatis.config.IdGeneratorSnowflake;
import com.duobaoyu.dby.supply.biz.enums.OrderParentTypeEnum;
import com.duobaoyu.dby.supply.biz.producer.SupplyChainMQProducer;
import com.duobaoyu.dby.supply.biz.strategy.message.order.base.BaseOrderAsyncHandler;
import com.duobaoyu.dby.supply.biz.util.IdGeneratorUtil;
import com.duobaoyu.dby.supply.common.biz.bo.message.ChannelMessageBO;
import com.duobaoyu.dby.supply.db.entity.order.Order;
import com.duobaoyu.dby.supply.db.entity.order.OrderConsignee;
import com.duobaoyu.dby.supply.db.entity.order.OrderProduct;
import com.duobaoyu.dby.supply.db.repository.order.OrderConsigneeRepository;
import com.duobaoyu.dby.supply.db.repository.order.OrderProductRepository;
import com.duobaoyu.dby.supply.db.repository.order.OrderRepository;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

import java.util.List;
import java.util.Objects;
import java.util.Set;

@Slf4j
@Component
@RequiredArgsConstructor
public class LinkedMallOrderConfirmChangeAsyncHandler extends BaseOrderAsyncHandler {

	private final TransactionTemplate transactionTemplate;
	private final OrderRepository orderRepository;
	private final IdGeneratorSnowflake idGeneratorSnowflake;
	private final OrderProductRepository orderProductRepository;
	private final SupplyChainMQProducer supplyChainMQProducer;
	private final OrderConsigneeRepository orderConsigneeRepository;


	@Override
	protected Set<String> channelCodes() {
		return Sets.newHashSet(ChannelCodeEnum.LINKED_MALL.getValue());
	}

	@Override
	protected Set<Integer> bizMessageTypes() {
		return Sets.newHashSet(BizMessageTypeEnum.CONFIRM_ORDER.getValue());
	}

	@Override
	protected Boolean executeHandler(ChannelMessageBO channelMessage, Object beforeResult) {
		LinkedMallConfirmOrderMessage linkedMallConfirmOrderMessage = JSON.parseObject(channelMessage.getMessage(), LinkedMallConfirmOrderMessage.class);
		Order order = orderRepository.getOne(Wrappers.<Order>lambdaQuery()
				.eq(StringUtils.isNotBlank(linkedMallConfirmOrderMessage.getOrderTradeSn()), Order::getOrderTradeSn, linkedMallConfirmOrderMessage.getOrderTradeSn())
				.eq(StringUtils.isNotBlank(linkedMallConfirmOrderMessage.getChannelTradeOrderSn()), Order::getChannelTradeOrderSn, linkedMallConfirmOrderMessage.getChannelTradeOrderSn())
				.eq(Order::getParentType, OrderParentTypeEnum.AFTER_SPLIT.getValue())
				.eq(StringUtils.isNotBlank(channelMessage.getChannelCode()), Order::getChannelCode, channelMessage.getChannelCode()));

		if (ObjectUtils.isEmpty(order)) {
			log.info("message:{},channelCode:{},data:{}","确认回调失败",channelMessage.getChannelCode(),JSON.toJSONString(channelMessage));
			return Boolean.FALSE;
		}

		this.orderStateCheck(order);

		List<OrderProduct> orderProductList = orderProductRepository.list(Wrappers.<OrderProduct>lambdaQuery().eq(OrderProduct::getOrderSn, order.getOrderSn()));
		OrderConsignee orderConsignee = orderConsigneeRepository.getOne(Wrappers.<OrderConsignee>lambdaQuery().eq(OrderConsignee::getOrderSn, order.getOrderSn()));

		List<Order> orderList = Lists.newArrayList();
		List<OrderProduct> orderProductNewList = Lists.newArrayList();
		List<OrderConsignee> orderConsigneeList = Lists.newArrayList();
		for (LinkedMallConfirmOrderMessage.OrderSubInfo orderSubInfo : linkedMallConfirmOrderMessage.getOrderSubInfoList()) {
			for (LinkedMallConfirmOrderMessage.OrderSubInfo.SkuInfo skuInfo : orderSubInfo.getSkuInfoList()) {
				Order orderNew = order.clone();
				ChannelCodeEnum channelCodeEnum = ChannelCodeEnum.getChannelCodeEnumByCode(order.getChannelCode());
				orderNew.setId(idGeneratorSnowflake.snowflakeId());
				orderNew.setOrderParentSn(order.getOrderSn());
				orderNew.setOrderSn(IdGeneratorUtil.getOrderSn(channelCodeEnum.getCode(), order.getServerName()));
				orderNew.setChannelOrderSn(skuInfo.getChannelOrderSn());
				orderNew.setChannelOrderParentSn(orderSubInfo.getChannelOrderParentSn());
				orderNew.setAfterSalesAllowed(Boolean.TRUE);
				orderNew.setParentType(OrderParentTypeEnum.AFTER_SPLIT.getValue());

				OrderProduct orderProduct = orderProductList.stream().filter(item -> {
					Boolean channelProductCode = StringUtils.isNotBlank(item.getChannelProductCode()) && StringUtils.isNotBlank(skuInfo.getChannelProductCode()) ? Objects.equals(item.getChannelProductCode(),skuInfo.getChannelProductCode()) : Boolean.TRUE;
					Boolean channelSkuCode = StringUtils.isNotBlank(item.getChannelSkuCode()) && StringUtils.isNotBlank(skuInfo.getChannelSkuCode()) ? Objects.equals(item.getChannelSkuCode(),skuInfo.getChannelSkuCode()) : Boolean.TRUE;
					return channelProductCode && channelSkuCode;
				}).findFirst().orElse(null);
				if (ObjectUtils.isEmpty(orderProduct)) {
					return Boolean.FALSE;
				}

				orderNew.setChannelOrderAmount(orderProduct.getPlatformAmount());
				orderNew.setOrderAmount(orderProduct.getPlatformSellAmount());
				orderNew.setChannelOrderRealityAmount(orderProduct.getChannelPayAmount());

				OrderProduct orderProductClone = orderProduct.clone();
				orderProductClone.setId(idGeneratorSnowflake.snowflakeId());
				orderProductClone.setOrderSn(orderNew.getOrderSn());
				OrderConsignee orderConsigneeClone = orderConsignee.clone();
				orderConsigneeClone.setId(idGeneratorSnowflake.snowflakeId());
				orderConsigneeClone.setOrderSn(orderNew.getOrderSn());
				orderList.add(orderNew);
				orderProductNewList.add(orderProductClone);
				orderConsigneeList.add(orderConsigneeClone);
			}
		}

		transactionTemplate.execute(new TransactionCallbackWithoutResult() {
			@Override
			protected void doInTransactionWithoutResult(@NotNull TransactionStatus transactionStatus) {
				orderRepository.update(Wrappers.<Order>lambdaUpdate().set(Order::getParentType, OrderParentTypeEnum.BEFORE_SPLIT.getValue())
						.eq(Order::getId, order.getId()));
				orderRepository.saveBatch(orderList);
				orderProductRepository.saveBatch(orderProductNewList);
				orderConsigneeRepository.saveBatch(orderConsigneeList);
			}
		});

		supplyChainMQProducer.orderAlterSend(order.getSupplyTradeSn(), order.getServerName());
		return Boolean.TRUE;
	}

}
